# -*- coding: UTF-8 -*-
"""
@auth:buxiangjie
@date:2021-10-11 09:26:00
@describe: 
"""

import json
import yaml
import decimal
import redis
import datetime
import os
import requests
import allure
import uuid

from log.ulog import Ulog
from typing import Optional
from requests.adapters import HTTPAdapter
from common.excep import excep

log = Ulog().logger_()


class Common:

	@staticmethod
	@excep
	@allure.step("请求准实时指标")
	def response(env: str, data: dict, headers=None, need_print: bool = False):
		"""请求准实时指标"""
		s = requests.session()
		# 设置请求重试次数
		s.mount("http://", HTTPAdapter(max_retries=3))
		s.mount("https://", HTTPAdapter(max_retries=3))
		if env == "test":
			url = "http://172.17.205.187:9601/item_request/fetch"
		elif env == "qa":
			url = "http://172.17.205.169:9601/item_request/fetch"
		elif env == "prod":
			url = "http://172.17.205.137:9601/item_request/fetch"
		# _uuid = str(uuid.uuid4())
		# trace_id = _uuid.split("-")[-2] + _uuid.split("-")[-1]
		# headers["X-B3-TraceId"] = trace_id
		# headers["X-B3-SpanId"] = trace_id
		log.info(
			f"请求地址:{url}\n"
			f"请求参数头:{headers}\n"
			f"请求参数:{json.dumps(data, ensure_ascii=False)}"
		)
		rep = s.post(
			url=url,
			headers=headers,
			json=data,
			timeout=30
		)
		rep.raise_for_status()
		reps = json.loads(rep.text)
		log.info(f"返回信息:{reps}\n请求响应时间:{rep.elapsed.total_seconds()}")
		# 使用ddt时需要打印
		if need_print is True:
			print(f"返回结果:{reps}")
		Common.get_rep_text(reps)
		return reps

	@staticmethod
	@excep
	@allure.step("数据加解密")
	def info_crypt(env: str, st: str, is_encrypt: bool):
		"""数据加解密"""
		s = requests.session()
		# 设置请求重试次数
		s.mount("http://", HTTPAdapter(max_retries=3))
		s.mount("https://", HTTPAdapter(max_retries=3))
		json_ = {
			"env": env,
			"data": st
		}
		if is_encrypt is True:
			crypt = "encrypt"
		elif is_encrypt is False:
			crypt = "decrypt"
		else:
			raise ValueError("未知的环境")
		rep = s.post(
			url=f"http://172.17.205.187:9018/support/aes/{crypt}",
			json=json_,
			timeout=30
		)
		rep.raise_for_status()
		reps = json.loads(rep.text)
		Common.get_rep_text(reps)
		return reps["result"]

	@staticmethod
	@excep
	def get_json_data(file: str, filename: str) -> dict:
		"""获取json文件的数据"""
		file = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + f'''/{file}/'''
		with open(file + filename, 'rb') as f:
			data = json.loads(f.read())
		return data

	@staticmethod
	@excep
	def get_yaml_data(path: str, filename: str) -> dict:
		"""读取yaml文件数据"""
		file = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + f'''/{path}/'''
		with open(file + filename, 'rb') as f:
			data = f.read()
		_data = yaml.load(data, Loader=yaml.FullLoader)
		return _data

	@staticmethod
	@excep
	def conn_redis(environment: str):
		"""连接redis"""
		conf = Common.get_yaml_data("config", "database.yaml")
		redis_conf = conf[environment]["redis"]
		pool = redis.ConnectionPool(**redis_conf)
		r = redis.Redis(connection_pool=pool)
		log.info(f"连接redis:{redis_conf}")
		return r

	# noinspection PyUnboundLocalVariable
	@staticmethod
	@excep
	def get_new_time(when: str, what: str, num: int, times: Optional[str] = "now") -> str:
		"""
		:param times:
		:param when: before or after
		:param what: days,minutes,seconds,hours,weeks
		:param num: 5
		:return: 2020-07-28 11:11:11
		"""
		if times == "now":
			start_time = datetime.datetime.now()
		else:
			pass
		new_times = ''
		if when == "after":
			if what == "days":
				new_times = start_time + datetime.timedelta(days=num)
			elif what == "hours":
				new_times = start_time + datetime.timedelta(hours=num)
			elif what == "seconds":
				new_times = start_time + datetime.timedelta(seconds=num)
			elif what == "minutes":
				new_times = start_time + datetime.timedelta(minutes=num)
			elif what == "weeks":
				new_times = start_time + datetime.timedelta(weeks=num)
		elif when == "before":
			if what == "days":
				new_times = start_time - datetime.timedelta(days=num)
			elif what == "hours":
				new_times = start_time - datetime.timedelta(hours=num)
			elif what == "seconds":
				new_times = start_time - datetime.timedelta(seconds=num)
			elif what == "minutes":
				new_times = start_time - datetime.timedelta(minutes=num)
			elif what == "weeks":
				new_times = start_time - datetime.timedelta(weeks=num)
		return str(new_times).split(".")[0]

	@staticmethod
	@excep
	def sub_table(env: str, asset_id: str):
		"""计算分表"""
		if env == "test":
			return str(int(asset_id) % 8 + 1)
		elif env == "qa":
			return str((int(asset_id) >> 22) % 8 + 1)
		else:
			raise ValueError("不支持的环境!")

	@staticmethod
	@allure.step("返回结果")
	def get_rep_text(rep):
		"""返回信息"""
		pass


class Encoder(json.JSONEncoder):
	"""
	重写json Encoder方法
	date datetime格式化字符串输出
	decimal转为float输出
	"""

	@excep
	def default(self, o):
		if isinstance(o, datetime.datetime):
			return o.strftime("%Y-%m-%d %H:%M:%S")
		elif isinstance(o, decimal.Decimal):
			return float(o)
		elif isinstance(o, datetime.date):
			return o.strftime("%Y-%m-%d")
		else:
			return json.JSONEncoder.default(self, o)
